/**
 * 应用配置 - 框架配置中心
 * 统一管理所有框架级配置项
 */

const defaultConfig = {
  app: {
    name: 'WWJCloud Backend',
    version: '1.0.0',
    port: 3001,
    environment: 'development',
    timezone: 'Asia/Shanghai',
    appKey: 'niucloud456$%^',
    defaultLanguage: 'zh_CN',
    supportedLocales: ['zh_CN', 'en_US'],
  },
  database: {
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'root',
    database: 'wwjcloud',
    synchronize: false,
    logging: true,
    connectionLimit: 20,
    acquireTimeout: 60000,
    timeout: 60000,
    cacheDurationMs: 30000,
    timezone: '+08:00',
    charset: 'utf8mb4',
  },
  redis: {
    host: 'localhost',
    port: 6379,
    password: '',
    db: 0,
    keyPrefix: 'wwjcloud:',
  },
  kafka: {
    clientId: 'wwjcloud-backend',
    brokers: ['localhost:9092'],
    groupId: 'wwjcloud-group',
    topicPrefix: 'wwjcloud.',
  },
  jwt: {
    secret: 'wwjcloud-jwt-secret-key-2024-very-long-secret',
    expiresIn: '24h',
    algorithm: 'HS256',
  },
  cache: {
    ttl: 3600,
    maxItems: 1000,
    prefix: 'cache:',
  },
  logging: {
    level: 'info',
    format: 'json',
    filename: 'logs/app.log',
  },
  upload: {
    path: 'uploads/',
    maxSize: 10 * 1024 * 1024,
    allowedTypes: ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx'],
  },
  throttle: {
    ttl: 60,
    limit: 100,
  },
  health: {
    startupCheckEnabled: true,
    startupTimeoutMs: 5000,
  },
  swagger: {
    enabled: process.env.SWAGGER_ENABLED === 'true' || true,
    title: process.env.SWAGGER_TITLE || 'WWJCloud API 文档',
    description:
      process.env.SWAGGER_DESCRIPTION ||
      'WWJCloud 基于 NestJS 的企业级后端 API 文档',
    version: process.env.SWAGGER_VERSION || '1.0.0',
    auth: {
      enabled: process.env.SWAGGER_AUTH_ENABLED === 'true' || true,
    },
    token: process.env.SWAGGER_TOKEN || '',
  },
};

function loadFromEnv() {
  return {
    app: {
      name: process.env.APP_NAME || defaultConfig.app.name,
      version: process.env.APP_VERSION || defaultConfig.app.version,
      port: parseInt(process.env.PORT || String(defaultConfig.app.port), 10),
      environment: process.env.NODE_ENV || defaultConfig.app.environment,
      timezone: process.env.TZ || defaultConfig.app.timezone,
      appKey:
        process.env.APP_APP_KEY ||
        process.env.APP_KEY ||
        process.env.AUTH_KEY ||
        defaultConfig.app.appKey,
      defaultLanguage:
        process.env.APP_DEFAULT_LANGUAGE ||
        process.env.DEFAULT_LANGUAGE ||
        defaultConfig.app.defaultLanguage,
      supportedLocales:
        process.env.APP_SUPPORTED_LOCALES?.split(',') ||
        defaultConfig.app.supportedLocales,
    },
    database: {
      host: process.env.DB_HOST || defaultConfig.database.host,
      port: parseInt(
        process.env.DB_PORT || String(defaultConfig.database.port),
        10,
      ),
      username: process.env.DB_USERNAME || defaultConfig.database.username,
      password: process.env.DB_PASSWORD || defaultConfig.database.password,
      database: process.env.DB_DATABASE || defaultConfig.database.database,
      synchronize: process.env.DB_SYNC === 'true',
      logging: process.env.DB_LOGGING === 'true',
      connectionLimit: parseInt(
        process.env.DB_CONN_LIMIT ||
          String(defaultConfig.database.connectionLimit),
        10,
      ),
      acquireTimeout: parseInt(
        process.env.DB_ACQUIRE_TIMEOUT_MS ||
          String(defaultConfig.database.acquireTimeout),
        10,
      ),
      timeout: parseInt(
        process.env.DB_QUERY_TIMEOUT_MS ||
          String(defaultConfig.database.timeout),
        10,
      ),
      cacheDurationMs: parseInt(
        process.env.DB_CACHE_DURATION_MS ||
          String(defaultConfig.database.cacheDurationMs),
        10,
      ),
      timezone: process.env.DB_TIMEZONE || defaultConfig.database.timezone,
      charset: process.env.DB_CHARSET || defaultConfig.database.charset,
    },
    redis: {
      host: process.env.REDIS_HOST || defaultConfig.redis.host,
      port: parseInt(
        process.env.REDIS_PORT || String(defaultConfig.redis.port),
        10,
      ),
      password: process.env.REDIS_PASSWORD || defaultConfig.redis.password,
      db: parseInt(process.env.REDIS_DB || String(defaultConfig.redis.db), 10),
      keyPrefix: process.env.REDIS_KEY_PREFIX || defaultConfig.redis.keyPrefix,
    },
    kafka: {
      clientId: process.env.KAFKA_CLIENT_ID || defaultConfig.kafka.clientId,
      brokers: (
        process.env.KAFKA_BROKERS || defaultConfig.kafka.brokers.join(',')
      ).split(','),
      groupId: process.env.KAFKA_GROUP_ID || defaultConfig.kafka.groupId,
      topicPrefix:
        process.env.KAFKA_TOPIC_PREFIX || defaultConfig.kafka.topicPrefix,
    },
    jwt: {
      secret: process.env.JWT_SECRET || defaultConfig.jwt.secret,
      expiresIn: process.env.JWT_EXPIRES_IN || defaultConfig.jwt.expiresIn,
      algorithm: process.env.JWT_ALGORITHM || defaultConfig.jwt.algorithm,
    },
    cache: {
      ttl: parseInt(
        process.env.CACHE_TTL || String(defaultConfig.cache.ttl),
        10,
      ),
      maxItems: parseInt(
        process.env.CACHE_MAX_ITEMS || String(defaultConfig.cache.maxItems),
        10,
      ),
      prefix: process.env.CACHE_PREFIX || defaultConfig.cache.prefix,
    },
    logging: {
      level: process.env.LOG_LEVEL || defaultConfig.logging.level,
      format: process.env.LOG_FORMAT || defaultConfig.logging.format,
      filename: process.env.LOG_FILENAME || defaultConfig.logging.filename,
    },
    upload: {
      path: process.env.UPLOAD_PATH || defaultConfig.upload.path,
      maxSize: parseInt(
        process.env.UPLOAD_MAX_SIZE || String(defaultConfig.upload.maxSize),
        10,
      ),
      allowedTypes:
        process.env.UPLOAD_ALLOWED_TYPES?.split(',') ||
        defaultConfig.upload.allowedTypes,
    },
    throttle: {
      ttl: parseInt(
        process.env.THROTTLE_TTL || String(defaultConfig.throttle.ttl),
        10,
      ),
      limit: parseInt(
        process.env.THROTTLE_LIMIT || String(defaultConfig.throttle.limit),
        10,
      ),
    },
    health: {
      startupCheckEnabled:
        (process.env.STARTUP_HEALTH_CHECK || 'true').toLowerCase() !== 'false',
      startupTimeoutMs: parseInt(
        process.env.STARTUP_HEALTH_TIMEOUT_MS ||
          String(defaultConfig.health.startupTimeoutMs),
        10,
      ),
    },
    swagger: {
      enabled: process.env.SWAGGER_ENABLED === 'true' || true,
      title: process.env.SWAGGER_TITLE || 'WWJCloud API 文档',
      description:
        process.env.SWAGGER_DESCRIPTION ||
        'WWJCloud 基于 NestJS 的企业级后端 API 文档',
      version: process.env.SWAGGER_VERSION || '1.0.0',
      auth: {
        enabled: process.env.SWAGGER_AUTH_ENABLED === 'true' || true,
      },
      token: process.env.SWAGGER_TOKEN || '',
    },
  };
}

function mergeConfig(defaultConfig: any, envConfig: any) {
  return {
    ...defaultConfig,
    ...envConfig,
    app: { ...defaultConfig.app, ...envConfig.app },
    database: { ...defaultConfig.database, ...envConfig.database },
    redis: { ...defaultConfig.redis, ...envConfig.redis },
    kafka: { ...defaultConfig.kafka, ...envConfig.kafka },
    jwt: { ...defaultConfig.jwt, ...envConfig.jwt },
    cache: { ...defaultConfig.cache, ...envConfig.cache },
    logging: { ...defaultConfig.logging, ...envConfig.logging },
    upload: { ...defaultConfig.upload, ...envConfig.upload },
    throttle: { ...defaultConfig.throttle, ...envConfig.throttle },
    health: { ...defaultConfig.health, ...envConfig.health },
    swagger: { ...defaultConfig.swagger, ...envConfig.swagger },
  };
}

export const appConfig = mergeConfig(defaultConfig, loadFromEnv());

export const config = {
  get() {
    return appConfig;
  },
  getApp() {
    return appConfig.app;
  },
  getDatabase() {
    return appConfig.database;
  },
  getRedis() {
    return appConfig.redis;
  },
  getKafka() {
    return appConfig.kafka;
  },
  getJwt() {
    return appConfig.jwt;
  },
  getCache() {
    return appConfig.cache;
  },
  getLogging() {
    return appConfig.logging;
  },
  getUpload() {
    return appConfig.upload;
  },
  getThrottle() {
    return appConfig.throttle;
  },
  getHealth() {
    return appConfig.health;
  },
  getSwagger() {
    return appConfig.swagger;
  },
  isProduction() {
    return appConfig.app.environment === 'production';
  },
  isDevelopment() {
    return appConfig.app.environment === 'development';
  },
  isTest() {
    return appConfig.app.environment === 'test';
  },
};

export default appConfig;
